#include <stdio.h>
#include "MyString.h"

void InitString(MyStr *s)
{
    s->string = NULL;
    s->len = 0;
    s->size = 0;
}

bool InsertString(MyStr *s,const char *str)
{
    return InsertByIndex(s,str,s->len);
}

bool InsertByIndex(MyStr *s,const char *str, int index)
{
    if(index < 0 || index > s->len)
    {
        printf("非法位置%d!\n",index);
        return false;
    }
    if(s->string == NULL)
    {
        if(index != 0)
        return false;

        s->size = (strlen(str)+1) * 2;
        s->string = malloc(s->size);
        if(s->string == NULL)
        {
            printf("Insert malloc error!\n");
            s->size = 0;
            return false;
        }
        strcpy(s->string,str);
        s->len = strlen(str);
        return true;
    }
    else
    {
        //内存足够
        int newlen = s->len + strlen(str);
        if((newlen+1) <= s->size)
        {
            INSERTSTR(temp,s->string+index);
            s->string[index] = '\0';
            strcat(s->string,str);
            strcat(s->string,temp.string);
            free(temp.string);

            s->len = newlen;
            return true;
        }
        else
        {
            //内存不够
            int newSize = newlen*2;
            char *newStr = realloc(s->string,newSize); 
            if(newStr == NULL)
            {
                printf("realloc error!\n");
                return false;
            }
            INSERTSTR(temp,newStr+index);
            newStr[index] = '\0';
            strcat(newStr,str);
            strcat(newStr,temp.string);
            

            s->string = newStr;
            s->len = newlen;
            s->size = newSize;
            return true;
        }
    }
    return false;
}

bool InsertChar(MyStr *s,char c,int index)
{
    char temp[2] = {0};
    temp[0] = c;
    return InsertByIndex(s,temp,index);
}

bool RemoveString(MyStr *s,const char *str)
{
    char *target = strstr(s->string,str);
    if(target == NULL)
    {
        printf("没找到字符串！\n");
        return false;
    }
    //找到str之后需要前置的位置
    char *back = target + strlen(str);
    while(*back != 0)
    {
        *target++ = *back++;
    }
    target = '\0';
    s->len = s->len - strlen(str);
    return true;
}

bool IsContains(MyStr *s,const char *str)
{
    if(strstr(s->string,str) == NULL)
    {
        return false;
    }
    return true;
}

bool IsEqual(MyStr *s,const char *str)
{
    if(strcmp(s->string,str) == 0)
    {
        return true;
    }
    return false;
}

MyStr ToUpper(const char *str)
{
    INSERTSTR(s,str);
    char *temp = s.string;
    while(*temp != '\0')
    {
        if(*temp >= 'a' && *temp <= 'z')
        *temp -= 32;
        temp++;
    }
    return s;
}
MyStr ToLower(const char *str)
{
    INSERTSTR(s,str);
    char *temp = s.string;
    while(*temp != '\0')
    {
        if(*temp >= 'A' && *temp <= 'Z')
        *temp += 32;
        temp++;   
    }
    return s;
}
void ClearString(MyStr *s)
{
    free(s->string);
    InitString(s);
}

bool IsEqualCaseInsensitive(MyStr *s,const char *str)
{
    MyStr s1 = ToUpper(s->string);
    MyStr s2 = ToUpper(str);
    if(strcmp(s1.string,s2.string) == 0)
    {
        ClearString(&s1);
        ClearString(&s2);
        return true;
    }
    ClearString(&s1);
    ClearString(&s2);
    return false;
}

int StringToInt(MyStr *s)
{
    return atoi(s->string);
}

double StringToDouble(MyStr *s)
{
    return atof(s->string);
}

MyStr CopyString(const MyStr *s)
{
    INSERTSTR(newStr,s->string);
    return newStr;
}

MyStr GetString(const char *str)
{
    INSERTSTR(newStr,str);
    return newStr;
}

void InitMyStrList(MyStrList *list)
{
    list->strlist = NULL;
    list->len = 0;
    list->size = 0;
}

bool InsertTail(MyStrList *list,const char *str)
{
    if(list->len == list->size)
    {
        int newSize = (list->len+1) *2;
        MyStr *newList = realloc(list->strlist,newSize *sizeof(MyStr));
        if(newList == NULL)
        {
            printf("Insertail realloc error!\n");
            return false;
        }
        list->size = newSize;
        list->strlist = newList;
    }
    list->strlist[list->len++] = GetString(str);
    return true;
}

MyStrList Split(const char *src,const char *delim)
{
    //创建一个字符串数组用于存放切割下来的字符串
    MyStrList list;
    InitMyStrList(&list);
    //备份字符串用于切割
    MyStr temp = GetString(src);

    char *str = strtok(temp.string,delim);
    while(str != NULL)
    {
        InsertTail(&list,str);
        str = strtok(NULL,delim);
    }
    ClearString(&temp);
    return list;
}

bool RemoveMyStrByIndex(MyStrList *list,int index)
{
    if(index < 0 || index >= list->len)
    {
        printf("非法位置%d\n",index);
        return false;
    }
    for(int i = index; i < list->len-1; i++)
    {
        list->strlist[i] = list->strlist[i+1];
    }
    list->len--;
    return true;
}

bool RemoveMyString(MyStrList *list,const char *str)
{
    for(int i = 0; i < list->len; i++)
    {
        if(IsEqual(&list->strlist[i],str) == true)
        {
            if(RemoveMyStrByIndex(list,i) == false)
            {
                return false;
            }
            i--;
        }
    }
    return true;
}

void DisplayStringList(MyStrList *list)
{
    for(int i = 0; i < list->len; i++)
    {
        printf("%s\n",list ->strlist[i].string);
    }
}

void ClearMyStringList(MyStrList *list)
{
    for(int i = 0; i < list->len; i++)
    {
        ClearString(&list->strlist[i]);
    }
    free(list->strlist);
    InitMyStrList(list);
}